package com.ztools.pc.service.impl.coupon;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ztools.common.model.pc.coupon.CouponRecord;
import com.ztools.common.model.pc.coupon.CouponTemplate;
import com.ztools.common.model.pc.export.CouponRecordExport;
import com.ztools.common.model.pc.information.WeChatMember;
import com.ztools.common.util.common.PageUtil;
import com.ztools.common.util.common.ServiceException;
import com.ztools.common.util.common.enumUnit.CouponSendEnum;
import com.ztools.common.util.pc.DictUtil;
import com.ztools.pc.async.CouponAsync;
import com.ztools.pc.mapper.coupon.CouponRecordMapper;
import com.ztools.pc.service.coupon.CouponRecordService;
import com.ztools.pc.service.coupon.CouponTemplateService;
import com.ztools.pc.service.information.MemberService;
import com.ztools.pc.service.sys.DictService;
import com.ztools.pc.util.ExcelUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: seeTools
 * @Date: 2023/5/11  15:50
 * @Version 1.0
 */
@Service
public class CouponRecordServiceImpl extends ServiceImpl<CouponRecordMapper, CouponRecord> implements CouponRecordService {

    @Resource
    private DictService dictService;
    @Resource
    private CouponTemplateService couponTemplateService;
    @Resource
    private MemberService memberService;
    @Resource
    private CouponRecordMapper couponRecordMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private CouponAsync couponAsync;
    @Resource
    private ExcelUtil excelUtil;

    @Override
    public Page<CouponRecord> findList(PageUtil<CouponRecord> pageUtil) {
        List<OrderItem> orders = new ArrayList<>();
        QueryWrapper<CouponRecord> queryWrapper = getQueryWrapper(pageUtil.getParams());
        Page<CouponRecord> pages = new Page<>(pageUtil.getPage(), pageUtil.getSize());
        // 排序数据  StrUtil.toUnderlineCase huTools将驼峰装换为下划线格式
        orders.add(new OrderItem(StrUtil.toUnderlineCase(pageUtil.getSortName()), "asc".equals(pageUtil.getSortOrder())));
        pages.setOrders(orders);
        Page<CouponRecord> page = page(pages, queryWrapper);
        dictionary(page.getRecords());
        return page;
    }

    @Override
    public boolean delete(CouponRecord record) {
        // 会员券包缓存
        couponAsync.refreshPacket(record.getMemberId());
        boolean b = false;
        CouponRecord recordById = getById(record);
        b = removeById(record);
        return b;
    }

    @Override
    public void deleteBatch(List<CouponRecord> couponRecordList) {
        for (CouponRecord couponRecord : couponRecordList) {
            couponAsync.refreshPacket(couponRecord.getMemberId());
            // 会员券包缓存
            couponAsync.refreshPacket(couponRecord.getMemberId());
        }
        couponRecordMapper.deleteBath(couponRecordList);
    }

    @Override
    public boolean add(CouponRecord record) {
        return save(record);
    }

    @Override
    public boolean sendCouponByPhone(CouponRecord record) {
        WeChatMember member = memberService.getById(record.getMemberId());
        List<CouponRecord> recordList = new ArrayList<CouponRecord>();
        if (member != null) {
            CouponTemplate couponTemplate = couponTemplateService.getById(record.getTemplateId());
            record.setCouponType(couponTemplate.getType());
            record.setState(0);
            record.setSendTime(new Date());
            record.setSendRoute(CouponSendEnum.PHONE.getSendRoute());
            record.setRemark(CouponSendEnum.PHONE.getName());
            for (int i = 0; i < record.getNumber(); i++) {
                recordList.add(record);
            }
            // 会员券包缓存
            couponAsync.refreshPacket(member.getId());
            return saveBatch(recordList);
        }
        throw new ServiceException("查询不到该会员");
    }

    @Override
    public boolean update(CouponRecord record) {
        // 会员券包缓存
        couponAsync.refreshPacket(record.getMemberId());
        boolean b = false;
        // 修改前先获取，在删除（乐观锁）
        CouponRecord recordById = getById(record);
        b = updateById(record);
        return b;
    }

    @Override
    public List<CouponRecord> findByObject(CouponRecord record) {
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>(record);
        return list(queryWrapper);
    }

    @Override
    public List<CouponRecord> getCouponTypeNumber(Long memberId) {
        List<CouponRecord> recordList = couponRecordMapper.getCouponTypeNumber(memberId);
        dictionary(recordList);
        return recordList;
    }

    /**
     * 字典翻译
     *
     * @param recordsList 对象集合
     */
    @Override
    public void dictionary(List<CouponRecord> recordsList) {
        for (CouponRecord record : recordsList) {
            dictionary(record);
        }
    }

    public QueryWrapper<CouponRecord> getQueryWrapper(CouponRecord couponRecord) {
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>(couponRecord);
        if (couponRecord.getStartDate() != null) {
            queryWrapper.lambda().ge(CouponRecord::getStartDate, couponRecord.getStartDate());
        }
        if (couponRecord.getEndDate() != null) {
            queryWrapper.lambda().ge(CouponRecord::getEndDate, couponRecord.getEndDate());
        }
        return queryWrapper;
    }


    @Override
    public List<CouponRecord> findExpireCoupon() {
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CouponRecord::getState, 2)
                .or().le(CouponRecord::getEndDate, new Date());
        return list(queryWrapper);
    }


    @Override
    public List<CouponRecord> getCouponUsable(CouponRecord couponRecord) {
        Date date = new Date();
        int week = DateUtil.dayOfWeek(date);
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().le(CouponRecord::getStartDate, date)
                .gt(CouponRecord::getEndDate, date)
                .eq(CouponRecord::getMemberId, couponRecord.getMemberId());
        List<CouponRecord> list = list(queryWrapper);
        dictionary(list);
        return list.stream().filter(item -> item.getDaysLimit().indexOf((week - 1) + "") > 0).collect(Collectors.toList());
    }

    @Override
    public void exportExcel(HttpServletResponse response, CouponRecord couponRecord) {
        long count = count();
        long sheetNumber = ExcelUtil.SHEET_NUMBER;
        long pageSize = excelUtil.getPageSize(sheetNumber, count);
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>(couponRecord);
        for (int i = 0; i < pageSize; i++) {
            Page<CouponRecord> pages = new Page<>(i, sheetNumber);
            Page<CouponRecord> page = page(pages, queryWrapper);
            List<CouponRecord> list = page.getRecords();
            dictionary(list);
            excelUtil.exportExcel(response, i, list, CouponRecordExport.class, "优惠券记录信息");
        }
    }

    public void dictionary(CouponRecord record) {
        if (record != null) {
            if (record.getTemplateId() != null) {
                CouponTemplate template = couponTemplateService.getById(record.getTemplateId());
                record.setTemplateName(template.getName());
                record.setAmountMeet(template.getAmountMeet());
                record.setDiscountAmount(template.getDiscountAmount());
                record.setDaysLimit(template.getDaysLimit());
                record.setBackground(template.getBackground());
            }
            if (record.getCouponType() != null) {
                record.setCouponTypeName(dictService.findByTypeCode(DictUtil.COUPON_TYPE, record.getCouponType() + ""));
            }
            if (StrUtil.isNotEmpty(record.getSendRoute())) {
                record.setSendRouteName(dictService.findByTypeCode(DictUtil.COUPON_ROUTE, record.getSendRouteName()));
            }
            if (record.getState() != null) {
                record.setStateName(dictService.findByTypeCode(DictUtil.COUPON_STATE, record.getState() + ""));
            }
            if (record.getMemberId() != null) {
                WeChatMember member = memberService.getById(record.getMemberId());
                record.setMemberName(member.getNickName());
                record.setMemberPhone(member.getPhone());
            }
        }
    }
}
